package cn.lcl.demo.util;

import cn.lcl.common.util.ProUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.log4j.Logger;

import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

/**
 * Created by licho on 2017/10/1 0001.
 */
public class FreeMarkerTemplate {
    private static  final Logger log= Logger.getLogger(FreeMarkerTemplate.class);
    private static final Configuration cfg=new Configuration(Configuration.VERSION_2_3_0);//FreeMarker的配置对象，可以配置为单例
    private static final String TMP_DIR="freemarker/template";//freemarker模板文件相对于classpath的基目录，
    private Template template;//代表某个template.
     /**
     * 基于某个模板名称来创建一个模板
     * @param name
     */
    public FreeMarkerTemplate(String name){
        try {
            this.template=cfg.getTemplate(name);
        } catch (IOException e) {
           log.error("template:"+name+"加载失败",e);
        }
    }
    static {
        ClassLoader loader=FreeMarkerTemplate.class.getClassLoader();
        URL classpathRUL=loader.getResource("");//获取classpath的url
        String classpath=URLDecoder.decode(classpathRUL.getPath());//类路径
        String tmp_dir= ProUtils.getProperty("tmp.dir");//查看是否存在tep.dir的配置参数
        cfg.setDefaultEncoding("UTF-8");//设置输出的默认编码
        if(log.isDebugEnabled()){
            log.debug("freemarker模板文件存放目录:"+classpath+(tmp_dir==null ? TMP_DIR:tmp_dir));
        }
        try {
            cfg.setDirectoryForTemplateLoading(new File(classpath+(tmp_dir==null ? TMP_DIR:tmp_dir)));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据模板和模型数据输出到控制台，一般用来进行测试
     * @param root  模板引擎的modal数据
     */
    public void printToConsole(Map<String,Object> root){
        printToOutStream(root,System.out);
    }

    /**
     * 根据模板和模型数据生成静态HTML文件
     * @param file  生成的文件路径
     * @param root  模型数据
     */
    public void printToHTMLFile(File file,Map<String,Object> root){
        try(BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(file))){
            printToOutStream(root,out);
        } catch (FileNotFoundException e) {
            log.error("文件不存在！",e);
        } catch (IOException e) {
            log.error("IO异常",e);
        }
    }

    /**
     * 将模型数据写入到输出流
     * @param root  模型数据
     * @param out   输出流
     */
    private void printToOutStream(Map<String,Object>root,OutputStream out){
        try {
            String encoding=cfg.getDefaultEncoding();
            template.process(root,new OutputStreamWriter(out,encoding));
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
